package com.lvkedu.dataforward.util;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * @function 字符串操作类
 */
public class StringUtils {

	public final static String UTF_8 = "utf-8";
	private static final String REGEX_ID_CARD = "(^\\d{18}$)|(^\\d{15}$)"; // 正则表达式：验证身份证

	/*
	 * @function 去除字符串中所有的空格
	 * @param str
	 * @return
	 */
	public static String replaceBlank(String str) {
		// String result = "";
		// if (str != null) {
		// Pattern p = Pattern.compile("\\n");
		// Matcher m = p.matcher(str);
		// result = m.replaceAll("");
		// }
		// return result.trim();
		String result = "";
		if (str != null)
			result = str.replace(" ", "");
		return result;
	}

	/**
	 * @function 过滤字符串中的特殊字符和emoji
	 * @param str
	 * @return
	 * @throws PatternSyntaxException
	 */
	public static String stringFilter(String str) throws PatternSyntaxException {
		// 只允许字母和数字
		// String regEx = "[^a-zA-Z0-9]";
		// 清除掉所有特殊字符
		// String regEx =
		// "[`~!@#$%^&*()+=|{}':;',//[//].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
		String regEx = "[`~^|':;',//[//]./——|‘；：”“’]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		String res = m.replaceAll("").trim();
		res = res.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "*");// 把emoji字符替换成*
		return res;
	}

	/*
	 * @function 将inputStream型转换成String型
	 * @param in_st
	 * @return
	 */
	public static String inputStream2String(InputStream in_st) {
		BufferedReader in = new BufferedReader(new InputStreamReader(in_st));
		StringBuffer buffer = new StringBuffer();
		String line = "";
		try {
			while ((line = in.readLine()) != null) {
				buffer.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer.toString();
	}

	/*
	 * @function 将String型转换成InputStream型
	 * @param str
	 * @return
	 */
	public static InputStream String2InputStream(String str) {
		ByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes());
		return stream;
	}

	/*
	 * @function 校验身份证
	 * @param idCard
	 * @return 校验通过返回true，否则返回false
	 */
	public static boolean isIDCard(String idCard) {
		return Pattern.matches(REGEX_ID_CARD, idCard);
	}

	/*
	 * @function 判断是否为邮箱
	 * @param string
	 * @return
	 */
	public static boolean isEmail(String string) {
		if (string == null || string.isEmpty())
			return false;
		Pattern p = Pattern
				.compile("^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$");
		Matcher m = p.matcher(string);
		return m.matches();
	}

	/*
	 * @function 判断是否为数字
	 * @param string
	 * @return
	 */
	public static boolean isNumber(String string) {
		if (string == null || string.isEmpty())
			return false;
		Pattern p = Pattern.compile("^(\\d+)$");
		Matcher m = p.matcher(string);
		return m.matches();
	}

	/**
	 * 判断该字符串是否为中文
	 * 
	 * @param string
	 * @return
	 */
	public static boolean isChinese(String string) {
		int n = 0;
		for (int i = 0; i < string.length(); i++) {
			n = (int) string.charAt(i);
			if (!(19968 <= n && n < 40869)) {
				return false;
			}
		}
		return true;
	}

	/*
	 * @function 验证邮政编码
	 * @param post
	 * @return
	 */
	public static boolean checkPost(String post) {
		if (post.matches("[1-9]\\d{5}(?!\\d)")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断是否为手机号码
	 * 
	 * @param mobiles
	 * @return
	 */
//	public static boolean isMobileNO(String mobiles) {
//		Pattern p = Pattern.compile("^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,6,7,8])|(18[0,5-9]))\\d{8}$");
//		Matcher m = p.matcher(mobiles);
//		return m.matches();
//	}

	/**
	 * 判断是否为手机号码
	 * 中国电信号段 133、149、153、173、177、180、181、189、199
		中国联通号段 130、131、132、145、155、156、166、175、176、185、186
		中国移动号段 134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188、198
		其他号段
		14号段以前为上网卡专属号段，如中国联通的是145，中国移动的是147等等。
		虚拟运营商
		电信：1700、1701、1702
		移动：1703、1705、1706
		联通：1704、1707、1708、1709、171
		卫星通信：1349
	 * @param phone
	 * @return
	 */
	public static boolean isMobileNO(String phone) {
		String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
		if (StringUtils.isEmpty(phone)||phone.length() != 11) {
			return false;
		} else {
			Pattern p = Pattern.compile(regex);
			Matcher m = p.matcher(phone);
			return m.matches();
		}
	}

	/*
	 * @function 如果字符串为null(NULL)、空字符串、只有空格、"null"都返回true,否则返回false
	 * @param value
	 * @return
	 * 
	 */
	public static boolean isEmpty(String value) {
		if (value == null || value .equals("") || "null".equalsIgnoreCase(value.trim())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断多个字符串是否相等，如果其中有一个为空字符串或者null，则返回false，只有全相等才返回true
	 */
	public static boolean isEquals(String... agrs) {
		String last = null;
		for (int i = 0; i < agrs.length; i++) {
			String str = agrs[i];
			if (isEmpty(str)) {
				return false;
			}
			if (last != null && !str.equalsIgnoreCase(last)) {
				return false;
			}
			last = str;
		}
		return true;
	}

	/**
	 * 格式化文件大小，不保留末尾的0
	 */
	public static String formatFileSize(long len) {
		return formatFileSize(len, false);
	}

	/**
	 * 格式化文件大小，保留末尾的0，达到长度一致
	 */
	public static String formatFileSize(long len, boolean keepZero) {
		String size;
		DecimalFormat formatKeepTwoZero = new DecimalFormat("#.00");
		DecimalFormat formatKeepOneZero = new DecimalFormat("#.0");
		if (len < 1024) {
			size = String.valueOf(len + "B");
		} else if (len < 10 * 1024) {
			// [0, 10KB)，保留两位小数
			size = String.valueOf(len * 100 / 1024 / (float) 100) + "KB";
		} else if (len < 100 * 1024) {
			// [10KB, 100KB)，保留一位小数
			size = String.valueOf(len * 10 / 1024 / (float) 10) + "KB";
		} else if (len < 1024 * 1024) {
			// [100KB, 1MB)，个位四舍五入
			size = String.valueOf(len / 1024) + "KB";
		} else if (len < 10 * 1024 * 1024) {
			// [1MB, 10MB)，保留两位小数
			if (keepZero) {
				size = String.valueOf(formatKeepTwoZero.format(len * 100 / 1024 / 1024 / (float) 100)) + "MB";
			} else {
				size = String.valueOf(len * 100 / 1024 / 1024 / (float) 100) + "MB";
			}
		} else if (len < 100 * 1024 * 1024) {
			// [10MB, 100MB)，保留一位小数
			if (keepZero) {
				size = String.valueOf(formatKeepOneZero.format(len * 10 / 1024 / 1024 / (float) 10)) + "MB";
			} else {
				size = String.valueOf(len * 10 / 1024 / 1024 / (float) 10) + "MB";
			}
		} else if (len < 1024 * 1024 * 1024) {
			// [100MB, 1GB)，个位四舍五入
			size = String.valueOf(len / 1024 / 1024) + "MB";
		} else {
			// [1GB, ...)，保留两位小数
			size = String.valueOf(len * 100 / 1024 / 1024 / 1024 / (float) 100) + "GB";
		}
		return size;
	}

	/*
	 * @function 获取指定的字符a第n次在字符串中出现的位置
	 * @param str 目标字符串
	 * @param idx 出现的次数n
	 * @param character 特定字符串a
	 * @return
	 */
	public static int getCharacterPosition(String str, int idx, String character) {
		// 这里是获取character符号的位置
		Matcher slashMatcher = Pattern.compile(character).matcher(str);
		int mIdx = 0;
		while (slashMatcher.find()) {
			mIdx++;
			// 当"/"符号第三次出现的位置
			if (mIdx == idx) {
				break;
			}
		}
		return slashMatcher.start();
	}

	/*
	 * @function 判断指定的字符在字符串中出现的次数
	 * @param str 目标字符串
	 * @param speChar 特定字符
	 * @return
	 */
	public static int speCharNum(String str, String speChar) {
		int num = 0;
		for (int i = 0; i < str.length(); i++) {
			String getS = str.substring(i, i + 1);
			if (getS.equals(speChar)) {
				num++;
			}
		}
		return num;
	}

	/*
	 * @function 将字符串转成ASCII
	 * @param value
	 * @return
	 */
	public static String stringToAscii(String value) {
		StringBuffer sbu = new StringBuffer();
		char[] chars = value.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			if (i != chars.length - 1) {
				sbu.append((int) chars[i]).append(",");
			} else {
				sbu.append((int) chars[i]);
			}
		}
		return sbu.toString();
	}

	/*
	 * @function 将ASCII转成字符串
	 * @param value
	 * @return
	 */
	public static String asciiToString(String value) {
		StringBuffer sbu = new StringBuffer();
		String[] chars = value.split(",");
		for (int i = 0; i < chars.length; i++) {
			sbu.append((char) Integer.parseInt(chars[i]));
		}
		return sbu.toString();
	}

	/*
	 * @function 提取中文中括号中内容，忽略中括号中的中括号
	 * @param msg
	 * @return
	 */
	public static List<String> extractMessageFromMiddleBra(String msg) {
		List<String> list = new ArrayList<String>();
		int start = 0;
		int startFlag = 0;
		int endFlag = 0;
		for (int i = 0; i < msg.length(); i++) {
			if (msg.charAt(i) == '【') {
				startFlag++;
				if (startFlag == endFlag + 1) {
					start = i;
				}
			} else if (msg.charAt(i) == '】') {
				endFlag++;
				if (endFlag == startFlag) {
					list.add(msg.substring(start + 1, i));
				}
			}
		}
		return list;
	}

	/**
	 * @function 提取英文小括号中的内容，忽略小括号中的小括号,支持多个小括号
	 * @param msg
	 * @return 返回String的集合
	 */
	public static List<String> extractMessageFromMinBra(String msg) {
		List<String> list = new ArrayList<String>();
		int start = 0;
		int startFlag = 0;
		int endFlag = 0;
		for (int i = 0; i < msg.length(); i++) {
			if (msg.charAt(i) == '(') {
				startFlag++;
				if (startFlag == endFlag + 1) {
					start = i;
				}
			} else if (msg.charAt(i) == ')') {
				endFlag++;
				if (endFlag == startFlag) {
					list.add(msg.substring(start + 1, i));
				}
			}
		}
		return list;
	}

	/**
	 * @function 提取英文小括号中的内容，忽略小括号中的小括号,只支持单个小括号
	 * @param msg
	 * @return String
	 */
	public static String extractMsgFromMinBra(String msg) {
		int start = 0;
		int startFlag = 0;
		int endFlag = 0;
		String str = "";
		for (int i = 0; i < msg.length(); i++) {
			if (msg.charAt(i) == '(') {
				startFlag++;
				if (startFlag == endFlag + 1) {
					start = i;
				}
			} else if (msg.charAt(i) == ')') {
				endFlag++;
				if (endFlag == startFlag) {
					str = msg.substring(start + 1, i);
				}
			}
		}
		return str;
	}

	/**
	 * 判断字符串的编码
	 *
	 * @param str
	 * @return
	 */
	public static String getEncoding(String str) {
		String encode[] = new String[] { "UTF-8", "ISO-8859-1", "GB2312", "GBK", "GB18030", "Big5", "Unicode",
				"ASCII" };
		for (int i = 0; i < encode.length; i++) {
			try {
				if (str.equals(new String(str.getBytes(encode[i]), encode[i]))) {
					return encode[i];
				}
			} catch (Exception ex) {
			}
		}

		return "";
	}

	/**
	 * @function 把字符串中每两个字符，由16进制ASCII码转换为普通字符，然后拼接成新的字符串
	 * @param raw
	 * @return
	 */
	public static String handleHexAsciiToString(String raw) {
		// 密码为空的时候不做处理直接返回字符串"null"
		if (raw == null || "".equals(raw))
			return "null";
		int len = raw.length();
		String[] result_array = new String[len / 2];
		StringBuffer sb = new StringBuffer(raw);
		int index;
		for (index = 2; index < sb.length(); index += 3) {
			sb.insert(index, ',');
		}
		String[] temp_array = sb.toString().split(",");
		for (int i = 0; i < temp_array.length; i++) {
			// 16进制Ascii转化为字符串
			String hex = temp_array[i];
			if (!isHexNumber(hex))
				return null;// 如果该字符串中存在不是
			result_array[i] = hexAsciiToString(temp_array[i]);
		}
		return StrArrToStr(result_array);
	}

	/**
	 * @function 字符串数组转化为字符串
	 * @param strArr
	 * @return
	 */
	private static String StrArrToStr(String[] strArr) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < strArr.length; i++) {
			sb.append(strArr[i]);
		}
		return sb.toString();
	}

	/**
	 * @function Ascii(16进制)转换为字符串
	 * @param hex
	 * @return
	 */
	public static String hexAsciiToString(String hex) {
		// 16进制转化为10进制
		int value = Integer.parseInt(hex, 16);
		// 10进制Ascii码转化为字符
		return Character.toString((char) value);
	}

	/**
	 * 字符串转换为16进制字符串
	 * 
	 * @param s
	 * @return
	 */
	public static String stringToHexString(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = (int) s.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str;
	}

	/**
	 * @function 判断字符串是否为16进制
	 * @param str
	 * @return
	 */
	public static boolean isHexNumber(String str) {
		Pattern p = Pattern.compile("[0-9a-fA-F]+");
		Matcher matcher = p.matcher(str);
		return matcher.matches();
	}

	/**
	 * @function 从字符串中获取到里面的数字（整数和小数，包括负数）
	 * @param str
	 * @return
	 */
	public static String getNumber(String str) {
		// 控制正则表达式的匹配行为的参数(小数)
		Pattern p = Pattern.compile("(-?\\d+\\.\\d+)");//匹配小数
		// Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequenceinput)方法得到该类的实例.
		Matcher m = p.matcher(str);
		// m.find用来判断该字符串中是否含有与"^-?([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*|0?\\.0+|0)$"相匹配的子串
		if (m.find()) {
			// 如果有相匹配的,则判断是否为null操作
			// group()中的参数：0表示匹配整个正则，1表示匹配第一个括号的正则,2表示匹配第二个正则,在这只有一个括号,即1和0是一样的
			str = m.group(1) == null ? "" : m.group(1);
		} else {
			// 如果匹配不到小数，就进行整数匹配
			p = Pattern.compile("(-?\\d+)");
			m = p.matcher(str);
			if (m.find()) {
				// 如果有整数相匹配
				str = m.group(1) == null ? "" : m.group(1);
			} else {
				// 如果没有小数和整数相匹配,即字符串中没有整数和小数，就设为空
				str = "";
			}
		}
		return str;
	}


	/**
	 * @function unicode编码转中文
	 * @param dataStr
	 * @return
	 */
	public static String decodeUnicode(final String dataStr) {
		int start = 0;
		int end = 0;
		final StringBuffer buffer = new StringBuffer();
		while (start > -1) {
			end = dataStr.indexOf("\\u", start + 2);
			String charStr = "";
			if (end == -1) {
				charStr = dataStr.substring(start + 2, dataStr.length());
			} else {
				charStr = dataStr.substring(start + 2, end);
			}
			char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。
			buffer.append(new Character(letter).toString());
			start = end;
		}
		return buffer.toString();
	}

	public static void main(String[] args) throws UnsupportedEncodingException {
		// String str = "jgpogj(pajg(ajgajgpag))(poajgagj123)(aopwghaw[gja[g)";
		// String str = "12℃";
		// System.out.println(getNumber(str));

		// System.out.println("16进制加密后：" + stringToHexString("CU_TAO"));
		// System.out.println("16进制解密后：" +
		// handleHexAsciiToString(stringToHexString("CU_TAO")));
		// String str = "\u4e2d\u56fd\u79fb\u52a8";
		// str = new String(str.getBytes(), "utf-8");
		// String str = "中国移动";
		// str = decodeUnicode(str);
		// String code = getEncoding("\u4e2d\u56fd\u79fb\u52a8");
		// System.out.println("str:" + str);
		//
		// String email = "qifan.wu9365@126.com";
		// System.out.println(isEmail(email));
		//
//		System.out.println(isHexNumber("ay"));
//        System.out.println(isMobileNO("19925333240"));
		// int value = Integer.parseInt("y0", 16);
        
        String str = "*-45℃";
        System.out.println(getNumber(str));

	}

}
